import { Inject, Injectable } from '@nestjs/common';
import { createHash, randomUUID } from 'node:crypto'
import { promises as fsPromises } from 'fs'
import * as path from 'path'
import { UploaderConfig } from './type/config';
import * as COS from 'cos-nodejs-sdk-v5'
const mime = require('mime-types');




@Injectable()
export class UploaderService {
    private minioClient:COS;

    constructor(
        @Inject('UPLOADER_CONFIG') private config: UploaderConfig,
    ) {
        
        if(!this.config.useLocal) {
            this.minioClient = new COS({
                SecretId: this.config.minio.accessKey,
                SecretKey: this.config.minio.secretKey,
            })
        }
    }


    delFiles(files:string[]) {
        files.forEach(file => {
            this.delFile(file)
        })
    }

    delFile(file:string) {
        try {

            if(this.config.useLocal) {
                return fsPromises.unlink(path.join(this.config.dist, file))
            }else {
                return this.minioClient.deleteObject({
                    Bucket: this.config.bucket,
                    Region: this.config.minio.region,
                    Key: file
                })
            }

            
        } catch (error) {
            
        }
    }


    put(file:Express.Multer.File, flag?:string|number) : Promise<string>;
    put(file:Express.Multer.File[], flag?:string|number) : Promise<Array<string>>;

    async put(file:Express.Multer.File | Express.Multer.File[], flag?:string|number) :Promise<string|Array<string>>{
        if(this.config.useLocal) {
            return this.putLocal(file, flag)
        }

        

        const date = new Date()
        let month = String(date.getMonth() + 1).padStart(2, '0')
        let day = String(date.getDate()).padStart(2, '0')



        let uuid:string = randomUUID()

        const subDir = String(date.getFullYear()) + '/' + month + '/' + day
        


        if(flag) {
            uuid = uuid + '&' + flag
        }

        if(Array.isArray(file)) { //多文件上传
            const fileNames:string[] = []
            // for(let i = 0; i < file.length; i ++) {
            //     const fileName = subDir + '/' + createHash('md5').update(uuid + '&' + file[i].originalname).digest('hex').toLowerCase() + path.extname(file[i].originalname)
            
            //     this.minioClient.putObject(this.config.bucket, fileName, file[i].buffer, file[i].buffer.length, {
            //         'Content-Type' : mime.lookup(file[i].originalname)
            //     })

            //     fileNames.push(fileName)
                
            // }

            return fileNames
        }else {


            const fileName = subDir + '/' + createHash('md5').update(uuid + '&' + file.originalname).digest('hex').toLowerCase() + path.extname(file.originalname)
        
            await this.minioClient.putObject({
                Bucket: this.config.bucket,
                Region: this.config.minio.region,
                Key: fileName,
                Body: file.buffer
            })

            // await this.minioClient.putObject(this.config.bucket, fileName, file.buffer, file.buffer.length, {
            //     'Content-Type' : mime.lookup(file.originalname)
            // })

            return fileName
        }

    }

    private async putLocal(file:Express.Multer.File | Express.Multer.File[], flag?:string|number) :Promise<string|Array<string>>{

        const date = new Date()
        let month = String(date.getMonth() + 1).padStart(2, '0')
        let day = String(date.getDate()).padStart(2, '0')



        let uuid:string = randomUUID()

        const uploadDist = this.config.dist
        const subDir = path.join(String(date.getFullYear()), month, day)
        


        if(flag) {
            uuid = uuid + '&' + flag
        }

        await fsPromises.mkdir(path.resolve(uploadDist, subDir), {recursive : true})


        if(Array.isArray(file)) { //多文件上传
            const fileNames:string[] = []
            for(let i = 0; i < file.length; i ++) {
                const fileName = path.join(subDir, createHash('md5').update(uuid + '&' + file[i].originalname).digest('hex').toLowerCase() + path.extname(file[i].originalname))
                
                fsPromises.writeFile(path.resolve(uploadDist, fileName), file[i].buffer)
                
                fileNames.push(fileName)
                
            }

            return fileNames
        }else {
            const fileName = path.join(subDir, createHash('md5').update(uuid + '&' + file.originalname).digest('hex').toLowerCase() + path.extname(file.originalname))
            await fsPromises.writeFile(path.resolve(uploadDist, fileName), file.buffer)
            return fileName
        }

    }
}
